home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
shade.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
10KB
|
481 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* shade -
* Support for describing materials and light sources by
* text files.
*
* Paul Haebetli - 1988
*/
#include "shade.h"
#include "stdio.h"
#include "gl.h"
#include "lum.h"
material *newmat()
{
return (material *)mymalloc(sizeof(material));
}
freemat(mat)
material *mat;
{
free(mat);
}
material *matfromfile(name)
char *name;
{
char fullname[100];
material *mat;
FILE *f;
findname(name,fullname,"GFXPATH");
f = fopen(fullname,"r");
if(!f) {
fprintf(stderr,"matfromfile: can't open file %s\n",fullname);
exit(1);
}
mat = matfromf(f);
fclose(f);
return mat;
}
material *matfromf(f)
FILE *f;
{
material *mat;
char token[256];
float r, g, b;
mat = newmat();
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
goto materror;
if(strcmp(token,"emission") != 0)
goto materror;
mat->emission.x = r;
mat->emission.y = g;
mat->emission.z = b;
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
goto materror;
if(strcmp(token,"ambient") != 0)
goto materror;
mat->ambient.x = r;
mat->ambient.y = g;
mat->ambient.z = b;
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
goto materror;
if(strcmp(token,"diffuse") != 0)
goto materror;
mat->diffuse.x = r;
mat->diffuse.y = g;
mat->diffuse.z = b;
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
goto materror;
if(strcmp(token,"specular") != 0)
goto materror;
mat->specular.x = r;
mat->specular.y = g;
mat->specular.z = b;
if(fscanf(f,"%s %f",token,&r) != 2)
goto materror;
if(strcmp(token,"shininess") != 0)
goto materror;
mat->shininess = r;
if(fscanf(f,"%s %f",token,&r) != 2)
goto materror;
if(strcmp(token,"alpha") != 0)
goto materror;
mat->alpha = r;
return mat;
materror:
freemat(mat);
return 0;
}
mattofile(name,mat)
char *name;
material *mat;
{
FILE *f;
f = fopen(name,"w");
if(!f) {
fprintf(stderr,"mattofile: can't open file %s\n",name);
exit(1);
}
mattof(f,mat);
fclose(f);
}
mattof(f,mat)
FILE *f;
material *mat;
{
fprintf(f,"emission %f %f %f\n",
mat->emission.x,mat->emission.y,mat->emission.z);
fprintf(f,"ambient %f %f %f\n",
mat->ambient.x,mat->ambient.y,mat->ambient.z);
fprintf(f,"diffuse %f %f %f\n",
mat->diffuse.x,mat->diffuse.y,mat->diffuse.z);
fprintf(f,"specular %f %f %f\n",
mat->specular.x,mat->specular.y,mat->specular.z);
fprintf(f,"shininess %f\n", mat->shininess);
fprintf(f,"alpha %f\n", mat->alpha);
}
matlerp(m0,m1,m,p)
material *m0, *m1, *m;
float p;
{
vlerp(&m0->emission,&m1->emission,&m->emission,p);
vlerp(&m0->ambient,&m1->ambient,&m->ambient,p);
vlerp(&m0->diffuse,&m1->diffuse,&m->diffuse,p);
vlerp(&m0->specular,&m1->specular,&m->specular,p);
m->shininess = flerp(m0->shininess,m1->shininess,p);
}
matprint(mat)
material *mat;
{
mattofile("/dev/tty",mat);
}
lamp *newlamp()
{
lamp *la;
la = (lamp *)mymalloc(sizeof(lamp));
la->next = 0;
return la;
}
freelamp(l)
lamp *l;
{
free(l);
}
lights *newlights()
{
lights *l;
l = (lights *)mymalloc(sizeof(lights));
l->lamps = 0;
return l;
}
freelights(li)
lights *li;
{
lamp *l, *nl;
l = li->lamps;
while(l) {
nl = l->next;
freelamp(l);
l = nl;
}
free(li);
}
lights *lightsfromfile(name)
char *name;
{
char fullname[100];
FILE *f;
lights *li;
findname(name,fullname,"GFXPATH");
f = fopen(fullname,"r");
if(!f) {
fprintf(stderr,"lightsfromfile: can't open file %s\n",fullname);
exit(1);
}
li = lightsfromf(f);
fclose(f);
return li;
}
lights *lightsfromf(f)
FILE *f;
{
lights *li;
lamp *la, *lastla;
char token[256];
float r, g, b, w;
int flag;
li = newlights();
la = 0;
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
goto lightserror;
if(strcmp(token,"ambient") != 0)
goto lightserror;
li->ambient.x = r;
li->ambient.y = g;
li->ambient.z = b;
if(fscanf(f,"%s %d",token,&flag) != 2)
goto lightserror;
if(strcmp(token,"localviewer") != 0)
goto lightserror;
li->localviewer = flag;
if(fscanf(f,"%s %f",token,&r) != 2)
goto lightserror;
if(strcmp(token,"attenconst") != 0)
goto lightserror;
li->attenconst = r;
if(fscanf(f,"%s %f",token,&r) != 2)
goto lightserror;
if(strcmp(token,"attenmult") != 0)
goto lightserror;
li->attenmult = r;
lastla = 0;
while(1) {
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
break;
if(strcmp(token,"ambient") != 0)
goto lightserror;
la = newlamp();
la->ambient.x = r;
la->ambient.y = g;
la->ambient.z = b;
if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4)
break;
if(strcmp(token,"color") != 0)
goto lightserror;
la->color.x = r;
la->color.y = g;
la->color.z = b;
if(fscanf(f,"%s %f %f %f %f",token,&r,&g,&b,&w) != 5)
break;
if(strcmp(token,"position") != 0)
goto lightserror;
la->position.x = r;
la->position.y = g;
la->position.z = b;
la->position.w = w;
if(!lastla) {
li->lamps = la;
lastla = la;
} else {
lastla->next = la;
lastla = la;
}
}
return li;
lightserror:
if(la)
freelamp(la);
freelights(li);
return 0;
}
lightstofile(name,li)
char *name;
lights *li;
{
FILE *f;
lamp *la;
f = fopen(name,"w");
if(!f) {
fprintf(stderr,"lightstofile: can't open file %s\n",name);
exit(1);
}
lightstof(f,li);
fclose(f);
}
lightstof(f,li)
FILE *f;
lights *li;
{
lamp *la;
fprintf(f,"ambient %g %g %g\n",
li->ambient.x,li->ambient.y,li->ambient.z);
fprintf(f,"localviewer %d\n",li->localviewer);
fprintf(f,"attenconst %g\n",li->attenconst);
fprintf(f,"attenmult %g\n",li->attenmult);
la = li->lamps;
while(la) {
fprintf(f,"ambient %f %f %f\n",
la->ambient.x,la->ambient.y,la->ambient.z);
fprintf(f,"color %f %f %f\n",
la->color.x,la->color.y,la->color.z);
fprintf(f,"position %f %f %f %f\n",
la->position.x,la->position.y,la->position.z,la->position.w);
la = la->next;
}
}
materialname(name)
char *name;
{
material *mat;
mat = matfromfile(name);
if(!mat)
return;
setmaterial(mat);
freemat(mat);
}
setmaterial(mat)
material *mat;
{
float mat_desc[40];
if(!mat) {
fprintf(stderr,"setmaterial: null material\n");
return;
}
mat_desc[0] = EMISSION;
mat_desc[1] = mat->emission.x;
mat_desc[2] = mat->emission.y;
mat_desc[3] = mat->emission.z;
mat_desc[4] = AMBIENT;
mat_desc[5] = mat->ambient.x;
mat_desc[6] = mat->ambient.y;
mat_desc[7] = mat->ambient.z;
mat_desc[8] = DIFFUSE;
mat_desc[9] = mat->diffuse.x;
mat_desc[10] = mat->diffuse.y;
mat_desc[11] = mat->diffuse.z;
mat_desc[12] = SPECULAR;
mat_desc[13] = mat->specular.x;
mat_desc[14] = mat->specular.y;
mat_desc[15] = mat->specular.z;
mat_desc[16] = SHININESS;
mat_desc[17] = mat->shininess;
mat_desc[18] = LMNULL;
mat_desc[18] = ALPHA;
mat_desc[19] = mat->alpha;
mat_desc[20] = LMNULL;
lmdef(DEFMATERIAL, 1, 21, mat_desc);
lmbind(MATERIAL, 1);
}
shadingoff()
{
lmbind(LMODEL,0);
}
shadingon()
{
lmbind(LMODEL,1);
}
lightsname(name)
char *name;
{
lights *li;
li = lightsfromfile(name);
if(!li)
return;
setlights(li);
freelights(li);
}
setlights(li)
lights *li;
{
float li_desc[40];
lamp *la;
int i;
if(!li) {
fprintf(stderr,"setlight: null light\n");
return;
}
li_desc[0] = AMBIENT;
li_desc[1] = li->ambient.x;
li_desc[2] = li->ambient.y;
li_desc[3] = li->ambient.z;
li_desc[4] = LOCALVIEWER;
li_desc[5] = li->localviewer;
li_desc[6] = ATTENUATION;
li_desc[7] = li->attenconst;
li_desc[8] = li->attenmult;
li_desc[9] = LMNULL;
lmdef(DEFLMODEL, 1, 10, li_desc);
lmbind(LMODEL, 1);
la = li->lamps;
for(i=1; i<=8; i++) {
if(!la) {
lmbind(LIGHT0+i-1, 0);
} else {
li_desc[0] = AMBIENT;
li_desc[1] = la->ambient.x;
li_desc[2] = la->ambient.y;
li_desc[3] = la->ambient.z;
li_desc[4] = LCOLOR;
li_desc[5] = la->color.x;
li_desc[6] = la->color.y;
li_desc[7] = la->color.z;
li_desc[8] = POSITION;
li_desc[9] = la->position.x;
li_desc[10] = la->position.y;
li_desc[11] = la->position.z;
li_desc[12] = la->position.w;
li_desc[13] = LMNULL;
lmdef(DEFLIGHT, i, 14, li_desc);
lmbind(LIGHT0+i-1, i);
la = la->next;
}
}
}
static int bwflag;
bwmode(b)
int b;
{
bwflag = b;
}
diffusergb(r,g,b)
float r, g, b;
{
float mat_desc[40];
if(bwflag)
r = g = b = LUM(r,g,b);
mat_desc[0] = DIFFUSE;
mat_desc[1] = r;
mat_desc[2] = g;
mat_desc[3] = b;
mat_desc[4] = LMNULL;
lmdef(DEFMATERIAL, 1, 5, mat_desc);
}